//SJGclock.js
//last upload beta v1.09

//global variables
var lastMinute,fontSize;
//globally accesible controls
var speakTxt,txt,chkAlarm,txtAlarm;
//user changeable settings
var granularity = app.LoadNumber("granularity", 99);
var alarmHour = app.LoadNumber("alarmHour", 99);
var alarmMin = app.LoadNumber("alarmMin", 0);
var alarmOn = app.LoadBoolean("alarmOn", false);
//
var publishedAPK = isFromApk();

//Called when application is started 
function OnStart() {
    app.PreventScreenLock(true);
    app.EnableBackKey(false);
    fontSize = calcFontSize("00:00")
    app.SetMenu("About,Licence");
  //Create a layout with objects vertically centered.
  var lay = app.CreateLayout("linear", "VCenter,FillX");
  // add top bar
    var lay_bar = app.CreateLayout("Linear", "Horizontal,Left, FillX");
    lay_bar.SetBackColor("#222222");
    speakTxt = app.CreateText(gran_message(granularity));
    speakTxt.SetTextSize(16);
    speakTxt.SetTextColor("#00ffff");
    speakTxt.SetPadding(0.01, 0, 0.01, 0);
    speakTxt.SetOnTouchUp(speakTxt_OnTouchUp);
    lay_bar.AddChild(speakTxt);
    
    var msgTxt = app.CreateText("Alarm time");
    msgTxt.SetTextSize(16);
    msgTxt.SetPadding(0.01, 0, 0.01, 0);
    lay_bar.AddChild(msgTxt);
    txtAlarm = app.CreateText(populate_alarm());
    txtAlarm.SetTextSize(16);
    txtAlarm.SetTextColor("#ffff00");
    txtAlarm.SetPadding(0.01, 0, 0.01, 0);
    txtAlarm.SetOnTouchUp(txtAlarm_OnTouchUp);
    lay_bar.AddChild(txtAlarm);

    chkAlarm = app.CreateCheckBox("Alarm on");
    chkAlarm.SetChecked(alarmOn);
    lay_bar.AddChild(chkAlarm);

    lay.AddChild(lay_bar); 
    var mnubtn = app.CreateText(" \u250b ");
    mnubtn.SetOnTouchUp(showMenu);
    mnubtn.SetBackColor("#ff444444");
    mnubtn.SetMargins(0.01,0,0,0);
    lay_bar.AddChild(mnubtn);


    //Create a text label and add it to layout.
    txt = app.CreateText("");
    txt.SetTextSize(fontSize.width);
    txt.SetOnTouchUp(txt_OnTouchUp);
    lay.AddChild(txt);
    
    //Add layout to app.    
    app.AddLayout(lay);
    displayTime();
}

function displayTime() {
    var d = new Date();
    var minute = d.getMinutes();
    //if no change, do nothing
    if (minute != lastMinute) {
        var hr = d.getHours();
        var min = (("0" + minute).slice(-2));
        txt.SetText(hr + ":" + min);
        //speak as often as required
        if ((granularity < 61) && (minute % granularity == 0)) {
            app.TextToSpeech(hr + ". " + min);
        }
        lastMinute = minute;
        if ((chkAlarm.GetChecked()) && (minute == alarmMin)
                && (hr == alarmHour)) {
            app.TextToSpeech("Alarm sounding");
            lastMinute=66; //speak alarm every 3 seconds
        }
    }
    setTimeout(displayTime, 3000);
}

function speakTxt_OnTouchUp() {
   switch (granularity){
   case 99: granularity=1;break;
   case 1: granularity=5;break;
   case 5: granularity=15;break;
   case 15: granularity=30;break;
   case 30: granularity=60;break;
   case 60: granularity=99;break;
  }
  speakTxt.SetText(gran_message(granularity));
}

function gran_message() {
    switch (granularity) {
    case 60:
        return "Speak every hour";
        break;
    case 30:
        return "Speak at 30 mins";
        break;
    case 15:
        return "Speak at 15 mins";
        break;
    case 5:
        return "Speak at 5 mins";
        break;
    case 1:
        return "Speak every minute";
        break;
    case 99:
        return "No speech";
        break;
    }
}
function txt_OnTouchUp(){
    if ( fontSize.width == fontSize.height ){
     //screen was probably off when app started 
     fontSize = calcFontSize("00:00");
     txt.SetTextSize( fontSize.width );
    }
    else{
      if ( ! publishedAPK ) rotateScreen();
    }
}

function setCurrTxtSize(num){  if(app.GetOrientation()=="Landscape")
    txtSizeL = num;
  else
    txtSizeP = num
  txt.SetTextSize(num);
  //var x = num / txt.GetWidth();
  //if( x  ><num ) txt.SetTextSize(x);
}

//Called when configuration changes. 
//(eg. When user rotates phone) 
function OnConfig()  
{               
  if(app.GetOrientation() == "Portrait"){
      txt.SetTextSize(fontSize.widthP)
  }
  else{
    txt.SetTextSize(fontSize.widthL);
  }
} 
//////
function populate_alarm() {
    if (alarmHour > 24) {
        var d = new Date();
        alarmHour = d.getHours();
        alarmMin = d.getMinutes();
    }
    return alarmHour + ":" + (("0" + alarmMin).slice(-2));
}

function txtAlarm_OnTouchUp() {
  ask("Type alarm time (hh:mm)", txtAlarm.GetText());    
}

function OnBack() {
  //save current settings
    app.SaveNumber("granularity", granularity);
    app.SaveNumber("alarmHour", alarmHour);
    app.SaveNumber("alarmMin", alarmMin);
    app.SaveBoolean("alarmOn", chkAlarm.GetChecked());
  //only exit if user presses Back again
  //within 4 seconds
    doubleBackKeyExit(4000);
}

function doubleBackKeyExit(millisecs) {
    app.EnableBackKey(true);
    app.ShowPopup("Press Back again to exit", "Bottom");
    setTimeout(disableBackKey, millisecs);
}
function disableBackKey() {
    app.EnableBackKey(false);
}

//Called when user touches Ok button.
function btnAskOk_OnTouch(){
  wds = edtAsk.GetText();
  wds = wds.replace(/[;,.\s]+/g, ':');
  tmp = wds.split( ":");
  if( tmp.length == 2 ){
    tmphr = parseInt((tmp[0]).trim());
    tmpmin = parseInt((tmp[1]).trim());
    if( isFinite(tmphr) && isFinite(tmpmin)
      && (tmphr > -1) && (tmphr < 24) 
      && (tmpmin > -1) && (tmpmin < 60) ){
        alarmHour = tmphr;
        alarmMin = tmpmin;
        txtAlarm.SetText(populate_alarm());
        chkAlarm.SetChecked(true);
    }   
  }
  unAsk();
}
///////////
//ask functionality
function createAskDialog( ){
  //Create a layout for Ask dialog
  layAsk = app.CreateLayout( "Linear" );
  layAsk.SetPadding( 0, 0.01, 0, 0 ); 
  layAsk.SetBackColor( "#ee666666" );
  layAsk.SetPosition(0, 0, 0.5, 0.5);
  layAsk.SetVisibility( "Hide" )
    
  txtAsk = app.CreateText("", 0.49);
  layAsk.AddChild(txtAsk);
  txtAsk.SetTextSize(12);
  txtAsk.SetMargins( 0, 0, 0, 0.05 );
  txtAsk.SetPadding( 0.05,0.05,0.05,0.05 );
  txtAsk.SetBackColor("#ff000000");
  edtAsk = app.CreateTextEdit("",0.4);
  edtAsk.SetMargins( 0, 0, 0, 0.05 );
  layAsk.AddChild(edtAsk);
  //Create button and add to  layout.
  btnAskOk = app.CreateButton( "Ok",-1,-1,"gray");
  btnAskOk.SetOnTouch( btnAskOk_OnTouch );
  layAsk.AddChild( btnAskOk );

  app.AddLayout(layAsk);
  return true;
}
function ask(msg, dflt){
  //open dialog
  try {
    var x = layAsk
  }
  catch(err) {
    var pause = createAskDialog();
  }
  txtAsk.SetText( msg );
  if(dflt != undefined)
    edtAsk.SetText( dflt );
  layAsk.Animate("SlideFromLeft");
}
function unAsk(){
  //close dialog
  app.HideKeyboard();//just in case
  layAsk.Animate("SlideToLeft");
}
////////
function calcFontSize(text) {
// this function expands on the work by Jorge Ramirez
    //create a local variable for a new layout
    var lay = app.CreateLayout("linear", "VCenter,FillXY");

    //create a test text
    var txt = app.CreateText(text);
    //use a big font to make the calculation more exact
    txt.SetTextSize(200);
    lay.AddChild(txt);
    //we don't want to be seen in the UI
    lay.SetVisibility("hide");
    app.AddLayout(lay);

    //Calculate the proportion between the text size used
    //and the height of the generated text
    //the result is the text size necessary to get a full size
    //(ie. 1) text

    var fullSize = [];
    if (! app.IsScreenOn() ){
        //make assumptions if screen is off
        //unlikely in real life
        fullSize.height = 128
        fullSize.width = 128
        fullSize.heightP = 128
        fullSize.widthP = 128
        fullSize.heightL = 128
        fullSize.widthL = 128
        fullSize.max = 128
        fullSize.min = 128
        fullSize.maxP = 128
        fullSize.minP = 128
        fullSize.maxL = 128
        fullSize.minL = 128
        return fullSize;
    }
    fullSize.height = 200 / txt.GetHeight();
    txt.SetTextSize(64);
    fullSize.width = 64 / txt.GetWidth();

    app.DestroyLayout(lay);

    var dh = app.GetDisplayHeight();
    var dw = app.GetDisplayWidth();
    if(dh > dw ){
      //portrait
      fullSize.heightP = fullSize.height;
      fullSize.widthP = fullSize.width;
      fullSize.heightL = fullSize.heightP * dw / dh
      fullSize.widthL = fullSize.widthP * dh / dw
    }
    else{
    //landscape
      fullSize.heightL = fullSize.height;
      fullSize.widthL = fullSize.width;
      fullSize.heightP = fullSize.heightL * dw / dh
      fullSize.widthP = fullSize.widthL * dh / dw   
    }
    fullSize.max = Math.max(fullSize.width, fullSize.height);
    fullSize.min = Math.min(fullSize.width, fullSize.height);
    fullSize.maxL = Math.max(fullSize.widthL, fullSize.heightL);
    fullSize.minP = Math.min(fullSize.widthP, fullSize.heightP);
    return fullSize
}

function rotateScreen(){
  if(app.GetOrientation() == "Portrait"){
     app.SetOrientation("Landscape");
  }
  else{
     app.SetOrientation("Portrait");
  }
}
function isFromApk(){ 
    if( app.GetAppPath() == "/Assets" ) 
      return true; 
      else return false; 
} 

function showMenu(){
    app.ShowMenu()
}
//Called when user selects a menu item.
function OnMenu( name ){ 
    var s;
    if(name=="About"){
        app.Alert("Really good \napp \nby Steve","About Speaking Clock");
    }
    else if(name=="Licence"){
        s = app.ReadFile("Misc/licence.txt");
        app.Alert( s, "Licence" );
    }
}

